package com.wh1200.mybatis.xmlless.model

import com.wh1200.mybatis.xmlless.XmlLessMapper
import com.wh1200.mybatis.xmlless.config.BaseResolverTest
import com.wh1200.mybatis.xmlless.replaceSpace
import jakarta.persistence.GeneratedValue
import jakarta.persistence.Id
import org.apache.ibatis.annotations.Param
import org.junit.jupiter.api.Test
import kotlin.reflect.jvm.javaMethod
import kotlin.test.assertContains
import kotlin.test.assertEquals
import kotlin.test.assertNotNull

interface TestEntityDAO : XmlLessMapper<TestEntity> {

  fun insert(entity: TestEntity)

  fun count(): Long

  fun deleteById(id: Int): Int

  fun existsById(id: Int): Boolean

  /**
   *
   * @param name
   * @param keyword
   * @return
   */
  fun findByNameAndDescLikeKeyword(name: String, keyword: String): List<TestEntity>

  /**
   *
   * @param keyword
   * @return
   */
  fun findByNameOrDescLikeKeyword(@Param("keyword") keyword: String): List<TestEntity>

}

/**
 * Created by 吴昊 on 2018/12/26.
 */
class QueryTest : BaseResolverTest(
    TestEntityDAO::class.java
) {

  @Test
  fun buildCountSql() {
    val sql = createQueryForMethod(
        TestEntityDAO::count.javaMethod!!
    ).sql
    assertNotNull(sql)
    assertContains(
        sql.replaceSpace(), "SELECT COUNT(*) FROM test_entity"
    )
  }

  @Test
  fun buildDeleteSql() {
    val sql = createQueryForMethod(
        TestEntityDAO::deleteById.javaMethod!!
    ).sql
    assertNotNull(sql)
    assertContains(sql, "test_entity.id = #{id}")
    assertContains(
        sql.replaceSpace(), "DELETE FROM test_entity"
    )
  }

  @Test
  fun buildExistsSql() {
    val sql = createQueryForMethod(
        TestEntityDAO::existsById.javaMethod!!
    ).sql
    assertNotNull(sql)
    assertContains(sql, "test_entity.id = #{id}")
    assertContains(
        sql.replaceSpace(), "SELECT COUNT(*) FROM test_entity"
    )
  }

  @Test
  fun buildInsertSql() {
    val sql = createQueryForMethod(
        TestEntityDAO::insert.javaMethod!!
    ).sql
    assertNotNull(sql)
    assertContains(sql, "INSERT INTO")
  }

  @Test
  fun resolveGroupBy() {
    val query1 = createQueryForMethod(
        TestEntityDAO::findByNameAndDescLikeKeyword.javaMethod!!
    ).query
    assertNotNull(query1)
    assertEquals(2, query1.resolveGroups().size)
    val query2 = createQueryForMethod(
        TestEntityDAO::findByNameOrDescLikeKeyword.javaMethod!!
    )
    assertEquals(null, query2.exception)
    val q = query2.query
    assertNotNull(q)
    assertEquals(2, q.resolveGroups().size)
  }

}

class TestEntity {


  @Id
  @GeneratedValue
  var id: Int = 0
  var name: String = ""
  var desc: String = ""

}
